package com.cch.cooperation.api.zone.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cch.cooperation.api.auth.service.UserServiceImpl;
import com.cch.cooperation.api.support.service.ContentCheckServiceImpl;
import com.cch.cooperation.api.zone.dto.ZonePostCommentAddDTO;
import com.cch.cooperation.api.zone.dto.ZonePostCommentDTO;
import com.cch.cooperation.api.zone.dto.ZonePostDTO;
import com.cch.cooperation.biz.common.util.BeanUtilEx;
import com.cch.cooperation.common.exception.BizException;
import com.cch.cooperation.common.util.SnowflakeIdUtil;
import com.cch.cooperation.dao.auth.model.User;
import com.cch.cooperation.dao.zone.mapper.ZonePostCommentMapper;
import com.cch.cooperation.dao.zone.model.ZonePostComment;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ZonePostCommentServiceImpl {

    @Resource
    private ZonePostCommentMapper mapper;
    @Resource
    private UserServiceImpl userService;
    @Lazy
    @Resource
    private ZonePostServiceImpl zonePostService;
    @Resource
    private ContentCheckServiceImpl contentCheckService;

    public List<ZonePostCommentDTO> getByZonePostIds(List<String> zonePostIds) {
        if (CollUtil.isEmpty(zonePostIds)) {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<ZonePostComment> query = new LambdaQueryWrapper<>();
        query.in(ZonePostComment::getZonePostId, zonePostIds);
        query.orderByDesc(ZonePostComment::getCreateTime);
        List<ZonePostComment> comments = mapper.selectList(query);
        // 查询关联用户信息
        List<String> userIds = comments.stream().map(o -> o.getUserId()).distinct().collect(Collectors.toList());
        userIds.addAll(comments.stream().filter(o -> ObjectUtil.isNotNull(o.getReplyUserId())).map(o -> o.getReplyUserId()).distinct().collect(Collectors.toList()));
        Map<String, User> userMap = userService.getMapByIds(userIds);
        // 聚合关联数据
        List<ZonePostCommentDTO> result = new ArrayList<>();
        for (ZonePostComment item : comments) {
            ZonePostCommentDTO comment = BeanUtilEx.copy(item, ZonePostCommentDTO.class);
            comment.setUser(userMap.get(comment.getUserId()));
            comment.setReplyUser(userMap.get(comment.getReplyUserId()));
            result.add(comment);
        }
        return result;
    }

    public Map<String, List<ZonePostCommentDTO>> getMapByZonePostIds(List<String> zonePostIds) {
        List<ZonePostCommentDTO> list = getByZonePostIds(zonePostIds);
        return list.stream().collect(Collectors.groupingBy(o -> o.getZonePostId()));
    }

    public ZonePostCommentDTO add(@Valid ZonePostCommentAddDTO req) {
        ZonePostDTO post = zonePostService.getById(req.getZonePostId());
        if (ObjectUtil.isNull(post)) {
            throw new BizException("该空间动态不存在");
        }
        contentCheckService.checkText(req.getContent());
        ZonePostComment comment = BeanUtilEx.copy(req, ZonePostComment.class);
        // 回复
        if (StrUtil.isNotEmpty(req.getReplyCommentId())) {
            ZonePostComment replyComment = mapper.selectById(req.getReplyCommentId());
            if (Objects.isNull(replyComment)) {
                throw new BizException("被回复的评论不存在");
            }
            comment.setReplyUserId(replyComment.getUserId());
        }
        comment.setId(SnowflakeIdUtil.getIdStr());
        comment.setCreateTime(new Date());
        mapper.insert(comment);
        return getByZonePostIds(Arrays.asList(req.getZonePostId())).stream().filter(o -> o.getId().equals(comment.getId())).findFirst().orElse(null);
    }

    public void deleteByZonePostId(String zonePostId) {
        LambdaQueryWrapper<ZonePostComment> query = new LambdaQueryWrapper<>();
        query.eq(ZonePostComment::getZonePostId, zonePostId);
        mapper.delete(query);
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteById(String id) {
        // 递归删除回复评论（如果存在性能问题则后续优化）
        LambdaQueryWrapper<ZonePostComment> query = new LambdaQueryWrapper<>();
        query.eq(ZonePostComment::getReplyCommentId, id);
        List<ZonePostComment> comments = mapper.selectList(query);
        for (ZonePostComment comment : comments) {
            deleteById(comment.getId());
        }
        // 删除回复的评论
        mapper.deleteById(id);
    }

}
